> 2 + 2
4
> 6 / 5
1.2
> 6 / -5
Precedence parsing error
cannot mix `/' [infixl 7] and prefix `-' [infixl 6]
in the same infix expression
> 6 / (-5)
-1.2
> True || False True > True && False False > not False True > 2 * 2 == 4 True > 2 * 2 /= 5 True
> 2 == "два" ?
:56:1:
No instance for (Num [Char])
arising from the literal `2'
Possible fix: add an instance declaration for (Num [Char])
In the first argument of `(==)', namely `2'
In the expression: 2 == "sad"
In an equation for `it': it = 2 == "sad"
Всегда с большой буквы
> :set +t
> 42
42 it :: Integer
> 3.1415
> True
> :t 42
42 :: Num a => a
(параметрический, специальный (ad hoc) полиморфизм)
42 + 1.2
it :: Double
> :t 42 + 8.2
42 + 8.2 :: Fractional a => a
> succ 9
10
> max 2.5 5.6
5.6
> 2 + max 2.5 5.6 + min 3.4 (succ 4)
11.0
> 2 + (max 2.5 5.6) + (min 3.4 (succ 4))
Ассоциативность слева, справа
2 ** 2 ** 3 / (2 ** 2) ** 3/ 2 ** (2 ** 3)
2 - 2 – 2 ?
Напишите выражение, высчитывающее минимальное число среди 10, 2, 5, -1, 99
lab1.hs
fac 0 = 1
fac n = n * fac (n-1)
console
> ghci
> :load ~lab1.hs
> fac 6
720
> let a = 20
> fac a
2432902008176640000
succ' n = n + 1
> succ' 9
10
square x = x * x
> square 4
16
squareIfLess5 = if x < 5 then square x else x
> squareIfLess5 3
9
> squareIfLess5 7
7
Строка – это список символов
> "Марьванна" "Марьванна" it :: [Char]
> 'М':"арьванна" > ['М','а','р','ь','в','а','н','н','а'] -- про списки ниже!
hello s = "Hello, " ++ s ++ "!" > hello "Марьванна" "Hello, \1052\1072\1088\1100\1074\1072\1085\1085\1072!"
> :t hello hello :: [Char] -> [Char]
> :t fac fac :: (Eq a, Num a) => a -> a -- ограничение - контекст (классы типов)
> :t max max :: Ord a => a -> a -> a
> :t squareIfLess5 squareIfLess5 :: (Num a, Ord a) => a -> a
(sumWithSquareOf) x y = x + square y > 3 `sumWithSquareOf` 5 28 > (sumWithSquareOf) 3 5 28
import Prelude hiding ((+)) x + y = x – y > 8 + 3 5
> (-) 23 13 10 > :t (-) (-) :: Num a => a -> a -> a
Пригодится для ФВП
> let lostNumbers = [4,8,15,16,23,42] > let cards = [3,7,12] > let mix = lostNumbers ++ cards > mix [4,8,15,16,23,42,3,7,12] > let lostNumbers = [13,666,1488]
> mix ?
[4,8,15,16,23,42,3,7,12]
> [1, "Гарри Поттер", 16.5] ?
> [] it :: [a] > [1, 13, 666] it :: [Integer] > [[1, 2], [3, 4]] it :: [[Integer]] > [[1, 2], [3, 4]] ++ [[5, 6]] it :: [[Integer]] > [[], []] it :: [[a]]
> [1, [2,3,4]] ?
-- ничего дельного
> 3 : mix [3,4,8,15,16,23,42,3,7,12]
> [3] : [1, 3, 4]
--фигвам
> [3] : [[5, 6]] it :: [[Integer]] > mix!!5 –- получение элемента 42
> 13 : [] ?
Список – это
1 : 2 : 3 : 4 : 5 : []
Всё остальное – синтаксический сахар
> head [1..5] -– [1, 2, 3, 4, 5] 1 > head []
*** Exception: Prelude.head: empty list > head [13] ?
> tail [1..5] [2, 3, 4, 5] > last [1..5] 5 > init [1..5] [1, 2, 3, 4] > length [2..6] 5 > null [1..5] False > null [] True
null' x = if (x=[]) then True else False
или
null' [] = True
null' _ = False
>:t null'
null :: [a] -> Bool
> take 4 [1..10]
[1, 2, 3, 4]
> take 4 [1..]
[1, 2, 3, 4]
> [1..] ?
> drop 4 [1..10]
[5, 6, 7, 8, 9, 10]
> take 4 (drop 7 "Hello, dude!")
"dude"
> drop 666 [1..10]
[]
> drop 4 [1..] ?
> minimum [10, 2, 5, -1, 99]
-1
> sum [1..10]
55
> product [1..10]
3628800
-- hmmm
fac n = product [1..n]
> fac 6
720
> elem 4 [1..10]
True
> elem 666 [1..10]
False
> 'o' `elem` "balloooon"
True
> [1,3..20]
[1,3,5,7,9,11,13,15,17,19]
> ['a'..'z']
"abcdefghijklmnopqrstuvwxyz"
> ['a'..] ?
> [0.1, 0.3 .. 1]
[0.1,0.3,0.5,0.7,0.8999999999999999,1.0999999999999999]
> take 11 (cycle "LOL ")
"LOL LOL LOL"
> take 10 (repeat 5)
[5,5,5,5,5,5,5,5,5,5]
> take 10 [5,5..]
[5,5,5,5,5,5,5,5,5,5]
> replicate 10 5 [5,5,5,5,5,5,5,5,5,5] > let replicate' how what = take how (repeat what)
let smth = ...
> [ a*a | a <- [1..10] ]
[1,4,9,16,25,36,49,64,81,100]
> [ [a,b] | a <- [1..3], b <- [3..7] ]
[[1,3],[1,4],[1,5],[1,6],[1,7],
[2,3],[2,4],[2,5],[2,6],[2,7],
[3,3],[3,4],[3,5],[3,6],[3,7]]
> [ [a,b] | a <- [1..3], b <- [3..7], 5 == a + b ]
[[1,4],[2,3]]
boomBangs xs =
[ if x < 10 then "BOOM!" else "BANG!" | x <- xs, odd x]
> boomBangs [7..13]
["BOOM!","BOOM!","BANG!","BANG!"]
for (let a = [], i = 0; i < 100000000000; i++) {
a.push(i);
}
> let a = [1..100000000000] -- и.. ничего
> let z = map (\x -> x * x) a
> let b = [ div 10 x | x <- [5,4..0] ] > take 5 b ? > take 6 b ?
Теорема ферма
-- списки
let rightTriangles = [[a,b,c] |
c <- [1..9], b <- [1..c], a <- [1..b], a^2 + b^2 == c^2]
-- кортежи
let rightTriangles = [(a,b,c) |
c <- [1..9], b <- [1..c], a <- [1..b], a^2 + b^2 == c^2]
> (1,2)
(1,2)
> ("Гарри Поттер", 13, 2.5)
("Гарри Поттер", 13, 2.5)
> fst (1,2)
1
> snd (1,2)
2
> fst (1,2,3) ?
> let (a,b,c) = (1,2,3)
-- (сопоставление с образцом, 3с. ниже)
> b
2
> [("Гарри Поттер", 13, 2.5),("Колобок", 1, 55.5)]
> type String = [Char] > type Name = String > type Person = (Name, Integer, Float) > let a = ("ГП", 12, 3.4)::Person > :t a a :: Person > :t [a, ("ГГ", 19, 0.2)] [a,("ГГ", 19, 0.2)] :: [Person]
Больше – создание новых типов
Опишите функцию, которая для данного числа n создает список из всех попарных сумм чисел от 1 до n. ( Т.е. [1+1, 1+2, 1+3, ..., 1+n, 2+1, 2+2, ..., n+n] - всего n*n элементов)
sayWhat :: Int -> String sayWhat 1 = "место встречи изменить нельзя" sayWhat 2 = "как обычно" sayWhat 3 = "суббота" sayWhat 4 = "я ничего не знаю" sayWhat 5 = "ненавижу хаскель, заберите меня отсюда" > sayWhat 3
Чего не хватает?
Non-exhaustive patterns in function sayWhat
sayWhat :: Int -> String -- кстати, тип можно не писать!
sayWhat 1 = "место встречи изменить нельзя"
sayWhat 2 = "как обычно"
sayWhat 3 = "суббота"
sayWhat 4 = "я ничего не знаю"
sayWhat 5 = "ненавижу хаскель, заберите меня отсюда"
sayWhat _ = "кто здесь?"
> sayWhat 3
sayWhat :: Int -> String sayWhat 1 = "место встречи изменить нельзя" sayWhat 2 = "как обычно" sayWhat _ = "кто здесь?" sayWhat 3 = "суббота" sayWhat 4 = "я ничего не знаю" sayWhat 5 = "ненавижу хаскель, заберите меня отсюда"
> sayWhat 3 > sayWhat 1
Pattern match(es) are overlapped
opinion :: (Int, String) -> String
opinion man =
"Я, " ++ snd man ++ " считаю \"" ++
sayWhat (fst man) ++ "\""
-- обратите внимание на скобки
> opinion (5, "Пупкин Васёк")
opinion :: (Int, String) -> String
opinion (num, name) =
"Я, " ++ name ++ " считаю \"" ++ sayWhat num ++ "\""
> show 1
"1"
> show (2, "Пупкин Васёк")
"(2, \"Пупкин Васёк\")"
> read "True" || False
True
bmiTell :: (RealFloat a) => a -> a -> String
bmiTell weight height
| weight / height ^ 2 <= 18.5 =
"You're underweight, you emo, you!"
| weight / height ^ 2 <= 25.0 =
"You're normal. Pffft, I bet you're ugly!"
| weight / height ^ 2 <= 30.0 =
"You're fat! Lose some weight, fatty!"
| otherwise =
"You're a whale, congratulations!"
bmiTell :: (RealFloat a) => a -> a -> String
bmiTell weight height
| bmi <= 18.5 =
"You're underweight, you emo, you!"
| bmi <= 25.0 =
"You're normal. Pffft, I bet you're ugly!"
| bmi <= 30.0 =
"You're fat! Lose some weight, fatty!"
| otherwise =
"You're a whale, congratulations!"
where bmi = weight / height ^ 2
bmiTell :: (RealFloat a) => a -> a -> String
bmiTell weight height
| bmi <= skinny =
"You're underweight, you emo, you!"
| bmi <= normal =
"You're normal.Pffft, I bet you're ugly!"
| bmi <= fat =
"You're fat! Lose some weight, fatty!"
| otherwise =
"You're a whale, congratulations!"
where
bmi = weight / height ^ 2
skinny = 18.5
normal = 25.0
fat = 30.0
bmiTell :: (RealFloat a) => a -> a -> String
bmiTell weight height
| bmi <= skinny =
"You're underweight, you emo, you!"
| bmi <= normal =
"You're normal.Pffft, I bet you're ugly!"
| bmi <= fat =
"You're fat! Lose some weight, fatty!"
| otherwise =
"You're a whale, congratulations!"
where
bmi = weight / height ^ 2
(skinny, normal, fat) = (18.5, 25.0, 30.0)
> [let square x = x * x in (square 5, square 3, square 2)]
> let square x = x * x in map square [5,3,2]
> (let a = 100; b = 200; c = 300 in a*b*c, let foo="Hey "; bar = "there!" in foo ++ bar)
some =
let opinion man = "Я, " ++ snd man ++ " считаю \"" ++ sayWhat (fst man) ++ "\""
dude = (5, "Пупкин Васёк")
in opinion dude
sayWhat :: Int -> String
sayWhat pos = "Моё мнение – " ++
сase pos of 1 -> "оставить как есть"
2 -> "как обычно"
3 -> "суббота"
4 -> "я ничего не знаю"
5 -> "ненавижу хаскель, заберите меня отсюда"
_ -> "кто здесь?"